#pragma once

#include <iostream>
#include <cstring>
#include <string>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <pthread.h>
#include <functional>

#include "Log.hpp"
#include "InetAddr.hpp"
#include "ThreadPool.hpp"
#include "Socket.hpp"

using namespace LogMudule;
using namespace ThreadPoolModule;

using task_t = std::function<void()>;
using handler_t = std::function<std::string(std::string &)>;

class TcpServer
{
private:
    void Handle(SockPtr ret)
    {
        LOG(LogLevel::DEBUG) << "进入处理 : " << ret->Fd();

        std::string package;
        while (1)
        {
            // 读取
            LOG(LogLevel::DEBUG) << "进入读取";
            std::string out;
            int n = ret->Recv(&out);
            // 读取成功，进行回显
            if (n > 0)
            {
                LOG(LogLevel::DEBUG) << "读取成功：" << out;
                package += out;
                std::string res = _handler(package);
                if (!res.empty())
                {
                    int m = ret->Send(res);
                    if (m < 0)
                    {
                        LOG(LogLevel::ERROR) << "send err...";
                        break;
                    }
                    // LOG(LogLevel::DEBUG) << "回显的数据：" << res;
                }
            }
            // 客户端退出
            else if (n == 0)
            {
                LOG(LogLevel::DEBUG) << "用户退出";
                break;
            }
            // 出错
            else
            {
                LOG(LogLevel::ERROR) << "read err...";
                printf("Error occurred: %d (%s)\n", errno, strerror(errno));
                break;
            }
        }

        ret->Close();
    }

public:
    TcpServer(uint16_t port)
        : _port(port),
          sp(std::make_shared<TcpSocket>())
    {
    }

    void InitServer()
    {

        LOG(LogLevel::DEBUG) << "准备进行初始化";
        sp->BuildTcpSocketMethod(_port);
        LOG(LogLevel::DEBUG) << "完成初始化";
    }

    void Start()
    {
        LOG(LogLevel::DEBUG) << "启动服务";

        while (1)
        {
            // 1.获取新的套接字
            InetAddr client;
            SockPtr ret = sp->Accepter(&client);
            if (ret == nullptr)
            {
                continue;
            }
            LOG(LogLevel::DEBUG) << "接收到连接: " << ret->Fd();
            
            // 多线程版本
            ThreadPool<task_t>::getInstance()->Equeue([this, ret](){this->Handle(ret);});

            //多进程版本
            // pid_t id = fork();
            // if (id == 0)
            // {
            //     sp->Close();
            //     if (fork() > 0)
            //         exit(0);
            //     Handle(ret);
            //     exit(0);
            // }
            // ret->Close();
            // waitpid(id, nullptr, 0);
        }
    }

    void Sethandler(handler_t handler)
    {
        _handler = handler;
    }

    ~TcpServer() = default;
private:
    uint16_t _port;
    SockPtr sp;
    handler_t _handler;
};